perm filename PIX.SAI[PIX,HPM]35 blob sn#275546 filedate 1977-04-12 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00047 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00006 00002	BEGIN "PIX"
C00012 00003	      IF CHR="?" THEN
C00015 00004	      IF CHR="T" THEN comment take a picture via a camera
C00017 00005	      IF CHR="↑" THEN comment optimize clip levels
C00022 00006	      IF CHR="←" THEN	comment  alter camera number
C00023 00007	      IF CHR="B" THEN	comment  alter bits/pixel, size and # to average
C00025 00008	      IF CHR="I" THEN	comment  input a file
C00027 00009	      IF CHR="%" THEN	comment  give information about a file
C00030 00010	      IF CHR="/" THEN	comment  input a portion of a file
C00033 00011	      IF CHR="O" THEN	comment  output a file
C00034 00012	      IF CHR="D"∨CHR="∂" THEN	comment  video synthesizer display
C00039 00013	      IF CHR="∃" THEN	comment  quick and dirty video synthesizer display
C00043 00014	      IF CHR="H" THEN	comment  high quality halftone
C00047 00015	      IF CHR="R" THEN	comment  random halftone
C00049 00016	      IF CHR="A" THEN	comment  arty bug halftone
C00051 00017	      IF CHR="X" THEN	comment  send previous halftone to the XGP
C00052 00018	      IF CHR=">" THEN	comment  make a DD buffer into an MIT transferrable file
C00053 00019	      IF CHR="<" THEN	comment  display MIT transferrable file
C00055 00020	      IF CHR="#" THEN	comment  switch a video switch output
C00056 00021	      IF CHR="P" THEN	comment  list a picture on the tty
C00059 00022	      IF CHR="α" THEN	comment  add a letter to a font
C00061 00023	      IF CHR="π" THEN comment  output dd buf to jarvis term.
C00062 00024	      IF CHR="λ" THEN	comment  make an XGPable file
C00064 00025	      IF CHR="C" THEN	comment  step past a certain number of pictures
C00065 00026	      IF CHR="K" THEN	comment  clear the video synthesizer
C00066 00027	      IF CHR="≡" THEN	comment  gronk synthesizer intensity table
C00068 00028	      IF CHR="S" THEN	comment  change size of displays
C00075 00029	      IF CHR="F" THEN	comment  high pass filter
C00076 00030	      IF CHR="&" THEN	comment  measure noise
C00077 00031	      IF CHR="L" THEN	comment  low pass filter
C00078 00032	      IF CHR="W" THEN	comment  select a window
C00081 00033	      IF CHR="Z" THEN	comment  change size of a picture
C00084 00034	      IF CHR="ε" THEN	comment  make DD buffer into a picture
C00086 00035	      IF CHR="*" THEN	comment  general geometric transformation
C00091 00036	      IF CHR="U" THEN	comment  remove blank border from a picture
C00093 00037	      IF CHR="N" THEN	comment  apply noise remover
C00094 00038	      IF CHR="V" THEN	comment  apply interest operator
C00095 00039	      IF CHR="M" THEN	comment  pixel modification
C00097 00040	      IF CHR="G" THEN	comment  graph a histogram
C00100 00041	      IF CHR="J" THEN	comment  graph a histogram
C00103 00042	      IF CHR="E" THEN	comment  apply histogram normalizer
C00106 00043	      IF CHR="Y" THEN	comment  apply vert sync loss correction
C00107 00044	      IF CHR="∞" THEN  comment for hackery
C00109 00045	      IF CHR="Q" THEN	comment  exit
C00110 00046	         BEGIN       comment  an unrecognized character
C00112 00047	      END
C00115 ENDMK
C⊗;
BEGIN "PIX"
REQUIRE "VIXHDR.SAI[VIS,HPM]" SOURCE_FILE;
REQUIRE "FILHDR.SAI[VIS,HPM]" SOURCE_FILE;
require "outdd.rel[s,pmf]" load_module;
external procedure outdd(string s; INTEGER SPOS(2), PPOS(-1));

INTEGER CAMERA,CHR,HIG,WID,BITS,PWANT,PHAVE,PDEFAULT;
STRING BACKLOG;    REAL SSIZE,HSIZE,SASPECT,HASPECT;
INTEGER SDISWID,SDISHIG,SYPOS;   REAL MAPTF;  INTEGER MAPBT;
INTEGER HDISWID,HDISHIG,HAPOS;
BOOLEAN INITED,SYNLAS,HAFTONE;
INTEGER BCL,TCL,SUMS,XEE,YEE,NRTRY;
boolean outddcalled;
REAL TASPECT,TLEN,TWID;
BOOLEAN TBRITE;
REAL LXB,LYB,UXB,UYB;
STRING INPOOT;

INTEGER PROCEDURE UCONV(INTEGER I);
   RETURN(IF I>'140 ∧ I≤'172 THEN I LAND '137 ELSE I);

INTEGER PROCEDURE PNEXTCH;
   RETURN(IF LENGTH(INPOOT)=0 THEN 0 ELSE INPOOT);

INTEGER PROCEDURE NEXTCH;
   BEGIN
   INTEGER NXC,M,FOO; OWN INTEGER EOF; OWN STRING FN;
   PRELOAD_WITH -1; OWN INTEGER ARRAY DEVICE[1:1];
   WHILE TRUE DO
   IF DEVICE[1]=-1 THEN
      BEGIN
      IF LENGTH(INPOOT)=0 THEN INPOOT←INCHWL&"↔";
      NXC←LOP(INPOOT);
      IF NXC="@" THEN
	 BEGIN
         STRING IFL;
	 DEVICE[1]←GETCHAN;
	 IFL←"";
	 WHILE (NXC←LOP(INPOOT))≠"↔" DO IFL←IFL&NXC;
	 PRSFIL("↓↓:↓↓.↓↓[↓↓,↓↓]");
         PRSFIL(FN);
         PRSFIL(IFL);
	 EOF←TRUE;
	 OPEN(DEVICE[1],DEVPRS,0,3,0,10,FOO,EOF);
	 LOOKUP(DEVICE[1],FILPRS,EOF);
	 BREAKSET(1,"","A");
	 BREAKSET(1,'12,"X");
	 BREAKSET(1,'12,"O");
         OUTSTR(" reading "&DEVPRS&":"&FILPRS&'15&'12);
         FN←DEVPRS&":"&FILPRS;
	 END
      ELSE RETURN(NXC);
      END
   ELSE
   IF EOF THEN
      BEGIN
      OUTSTR(" finished "&FN&'15&'12);
      RELEASE(DEVICE[1]);
      DEVICE[1]←-1;
      END
   ELSE
      BEGIN
      NXC←INPUT(DEVICE[1],1);
      IF NXC='15 THEN NXC←"↔";
      RETURN(NXC);
      END;
   END;

INTEGER PROCEDURE UINCHRW;
   BEGIN
   INTEGER CH;
   DO CH←NEXTCH UNTIL CH≠"↔";
   IF EQU(INPOOT,"↔") THEN NEXTCH;
   RETURN(CH);
   END;

STRING PROCEDURE UINCHWL;
   BEGIN
   STRING UINCH; INTEGER NC;
   UINCH←"";
   WHILE (NC←NEXTCH)≠"↔" DO UINCH←UINCH&NC;
   RETURN(UINCH);
   END;

PROCEDURE UOUTSTR(STRING STRN);
   IF PNEXTCH=0 THEN OUTSTR(STRN);
      
LXB←LYB←-1; UXB←UYB←1;
BCL←7; TCL←0;
YEE←0; XEE←1;
CAMERA←'54; BACKLOG←""; INITED←FALSE; SYNLAS←TRUE; HAFTONE←FALSE;
HIG←260; WID←288; BITS←4; SUMS←1;
PDEFAULT←PWANT←PHAVE←PIXDIM(HIG,WID,BITS);

TASPECT←3/10; TLEN←21; TWID←80;  TBRITE←TRUE;  NRTRY←15;
SSIZE←HSIZE←.5; SASPECT←HASPECT←481/512;   MAPTF←1;  MAPBT←4;
SDISWID←HDISWID←SDISHIG←HDISHIG←1; HAPOS←SYPOS←1;
INPOOT←"";

DDINIT; SCREEN(-1,-1,1,1);
synmap(0,-1);
outddcalled←false;

OUTSTR("TYPE ?<CR> FOR COMMAND LIST"&'15&'12);

WHILE TRUE DO
   BEGIN
   INTEGER ARRAY PIC[0:PHAVE];

   IF PHAVE=PDEFAULT THEN 
      BEGIN
      MAKPIX(HIG,WID,BITS,PIC[0]);
      INITED←TRUE;
      END;

   WHILE PHAVE=PWANT DO
      BEGIN
      MAPBT←MAPBT MAX PIC[BYBI];
      IF LENGTH(BACKLOG)=0 THEN
         BEGIN
         OUTSTR("*");
         DO CHR←UCONV(UINCHRW) UNTIL CHR≠'15;
         END
      ELSE CHR←UCONV(LOP(BACKLOG));
      IF CHR="?" THEN
         BEGIN
         outddcalled←true;
         OUTdd("                        Pix Commands

""T"" take a picture from currently selected source
""B"", ""↑"", ""←"" set video digitizer parameters.
     B bits/sample, window, ↑ clip levels, ← video source (default=44)
""I"", ""O"" input or output pictures from or to a file
""%"", ""/"" for very large files. % gets dimensions, / reads in a part

""D"", ""∂"", ""∃"" display on the video synthesizer, ∂ with grid, ∃ fast
""H"", ""R"" or ""A"" display it as a halftone (H good, R random, A arty)
""P"", ""λ"" for a character display. P on the terminal, λ for halftone fonts
""X"", ""ε"", ""α"", ""π"", "">"", ""<""  copy the last DD display
     X to XGP, ε to picture, α to font, π to PJ dpy, > to and < from MIT files

""S"" set multiplicity, shape and size of displays. default=1x1, 1/2 size
""C"" skip past a number of slots (when displaying multiple pictures)
""K"", ""≡"" affect video synthesizer, K clear it, ≡ adjust intensity table
""#"" connect a foreign video switch line to a given channel

""W"", ""Z"", ""*"" geometric tranforms. W window, Z size, * general
""Y"", ""U"" fix a picture. Y vertical sync, U remove black border
""F"", ""L"", ""N"" or ""V"" filter the picture
     F high pass, L low pass (halve resolution), N remove noise, V interest
""G"" or ""J"" graph the numbers of each grey level. G raw, J integrated
""E"" enhance a picture (normalize the instances of each grey level)
""M"" modify grey levels via a function (entered piecewise linear)
""Q"" quit

Commands may combined in a line using ↔ for carriage return

");

         END
      ELSE
      IF CHR="T" THEN comment take a picture via a camera;
         BEGIN
         INTEGER NRT;
         IF PHAVE=PDEFAULT THEN
            BEGIN
            IF ¬INITED THEN
               BEGIN
               MAKPIX(HIG,WID,BITS,PIC[0]);
               INITED←TRUE;
               END;
            NRT←CAMPIX(CAMERA,YEE,XEE,PIC[0],SUMS,BCL,TCL,NRTRY);
            OUTSTR("  "&(IF NRT<0 THEN " aborted "&DEVPRS&":"&FILPRS ELSE
                   CVS(NRT)&" RETR"&(IF NRT≠1 THEN "IES" ELSE "Y"))&'15&'12);
            IF NRT≥0 THEN
            OUTSTR(CVS(PIC[PCLN])&" LINES x "&CVS(PIC[LNBY])&
               " BYTES/LINE x "&CVS(PIC[BYBI])&" BITS/BYTE"&'15&'12);
            END
         ELSE
            BEGIN
            BACKLOG←"T";
            PWANT←PDEFAULT;
            END;
         END
      ELSE
      IF CHR="↑" THEN comment optimize clip levels;
         BEGIN
         STRING SIN; INTEGER FOO;
         UOUTSTR("<CR> FOR AUTO OR TCLIP, BCLIP (0≤TCLIP≤BCLIP≤7):"); SIN←UINCHWL;
         IF LENGTH(SIN)≠0 THEN
            BEGIN
	    TCL←INTSCAN(SIN,FOO);
	    BCL←INTSCAN(SIN,FOO);
            END
         ELSE
            BEGIN
            INTEGER NRT;
            NRT←CLPADJ(CAMERA,BCL,TCL);
            IF NRT<0 THEN OUTSTR(" aborted "&DEVPRS&":"&FILPRS&'15&'12) ELSE
            IF NRT>0 THEN OUTSTR("  "&CVS(NRT)&
                 " RETR"&(IF NRT≠1 THEN "IES" ELSE "Y")&'15&'12);
            OUTSTR("TCLIP="&CVS(TCL)&"  BCLIP="&CVS(BCL)&'15&'12);
            END;
         END
      ELSE
      IF CHR="←" THEN	comment  alter camera number;
         BEGIN
         UOUTSTR(" CHANNEL NUMBER:");
         CAMERA←CVO(UINCHWL);
         BCL←7; TCL←0;
         END
      ELSE
      IF CHR="B" THEN	comment  alter bits/pixel, size and # to average;
         BEGIN
         INTEGER T,FOO; STRING INST;

         UOUTSTR(" PICTURE HEIGHT, WIDTH (NOW "&CVS(HIG)&", "&CVS(WID)&"):");
         INST←UINCHWL;
         IF LENGTH(INST)>2 THEN
            BEGIN
            HIG←INTSCAN(INST,FOO); WID←INTSCAN(INST,FOO);
            END;

         UOUTSTR(" PICTURE YEDGE, XEDGE (NOW "&CVS(YEE%2)&", "&CVS(XEE)&"):");
         INST←UINCHWL;
         IF LENGTH(INST)>2 THEN
            BEGIN
            YEE←2*INTSCAN(INST,FOO); XEE←INTSCAN(INST,FOO) MAX 1;
            END;

         UOUTSTR(" NO. OF PICTURES TO AVERAGE (NOW "&CVS(SUMS)&"):");
         T←CVD(UINCHWL); IF T>0 THEN SUMS←T;

         UOUTSTR(" BITS/PIXEL (NOW "&CVS(BITS)&"):");
         T←CVD(UINCHWL); IF T>0 THEN BITS←T MIN 36;

         UOUTSTR(" SUPPRESS PARTIAL RETRIES?");
         NRTRY←(IF (UINCHWL LAND '137)="Y" THEN -200 ELSE 100);

         PDEFAULT←PWANT←PIXDIM(HIG,WID,BITS);

         END
      ELSE
      IF CHR="I" THEN	comment  input a file;
         BEGIN
         OWN STRING FN;
         IF LENGTH(BACKLOG)=0 THEN
            BEGIN
            PRSFIL("↓↓:↓↓.↓↓[↓↓,↓↓]");
            PRSFIL(FN);
            UOUTSTR("FILE:");
            IF LENGTH(FN←UINCHWL)>0 ∧ PFLDIM(FN)>0 THEN
                BEGIN
                PWANT←PFLDIM(FN);
                BACKLOG←"I"&FN;
                END ELSE OUTSTR("aborted "&DEVPRS&":"&FILPRS&'15&'12);
            END
         ELSE
            BEGIN
            GETPFL(BACKLOG,PIC[0]);
            OUTSTR(CVS(PIC[PCLN])&" LINES x "&CVS(PIC[LNBY])&
               " BYTES/LINE x "&CVS(PIC[BYBI])&" BITS/BYTE"&'15&'12);
            BACKLOG←"";
            INITED←FALSE;
            FN←DEVPRS&":"&FILPRS;
            END;
         END
      ELSE
      IF CHR="%" THEN	comment  give information about a file;
         BEGIN
         STRING FN;
         UOUTSTR("FILE:");
         IF LENGTH(FN←UINCHWL)>0 ∧ PFLDIM(FN)>0 THEN
            BEGIN
            INTEGER ARRAY HD[0:10];
            GETPFD(FN,HD[0]);
            OUTSTR(CVS(HD[PCLN])&" LINES x "&CVS(HD[LNBY])&
               " BYTES/LINE x "&CVS(HD[BYBI])&" BITS/BYTE"&'15&'12);
            END ELSE OUTSTR("aborted "&DEVPRS&":"&FILPRS&'15&'12);
         END
      ELSE
      IF CHR="/" THEN	comment  input a portion of a file;
         BEGIN
         STRING FN,INFL;  OWN INTEGER LY,LX,HY,HX,XCMP,YCMP,BT;
         INTEGER FOO;
         IF LENGTH(BACKLOG)=0 THEN
            BEGIN
            UOUTSTR("FILE:");
            IF LENGTH(FN←UINCHWL)>0 ∧ PFLDIM(FN)>0 THEN
               BEGIN
               INTEGER ARRAY HD[0:10];
               GETPFD(FN,HD[0]);
               OUTSTR(CVS(HD[PCLN])&" LINES x "&CVS(HD[LNBY])&
                  " BYTES/LINE x "&CVS(HD[BYBI])&" BITS/BYTE"&'15&'12);
               BACKLOG←"/"&FN;
               UOUTSTR("LOW Y, LOW X (IN PIXELS):"); INFL←UINCHWL;
               LY←INTSCAN(INFL,FOO);  LX←INTSCAN(INFL,FOO);
               LY←(LY MAX 0) MIN (HD[PCLN]-1); LX←(LX MAX 0) MIN (HD[LNBY]-1);
               UOUTSTR("LINEAR COMPRESSION FACTORS (Y, X):"); INFL←UINCHWL;
               XCMP←INTSCAN(INFL,FOO);
               YCMP←INTSCAN(INFL,FOO);
               XCMP←XCMP MAX 1;
               IF YCMP≤0 THEN YCMP←XCMP;
               UOUTSTR("HEIGHT, WIDTH AND BITS/PIXEL OF RESULT:"); INFL←UINCHWL;
               HY←INTSCAN(INFL,FOO);  HX←INTSCAN(INFL,FOO);
               IF HY=0 THEN HY←256; IF HX=0 THEN HX←256;
               HY←(HY MAX 1) MIN (HD[PCLN]-LY)%YCMP;
               HX←(HX MAX 1) MIN (HD[LNBY]-LX)%XCMP;
               BT←INTSCAN(INFL,FOO); IF BT=0 THEN BT←HD[BYBI];
               BT←(BT MAX 1) MIN 36;
               PWANT←PIXDIM(HY,HX,BT);
               END ELSE OUTSTR("aborted "&DEVPRS&":"&FILPRS&'15&'12);
            END
         ELSE
            BEGIN
            MAKPIX(HY,HX,BT,PIC[0]);
            GETPFP(BACKLOG,PIC[0],LY,LX,YCMP,XCMP);
            OUTSTR(CVS(PIC[PCLN])&" LINES x "&CVS(PIC[LNBY])&
               " BYTES/LINE x "&CVS(PIC[BYBI])&" BITS/BYTE"&'15&'12);
            BACKLOG←"";
            INITED←FALSE;
            END;
         END
      ELSE
      IF CHR="O" THEN	comment  output a file;
         BEGIN
         OWN STRING FN;
         PRSFIL("↓↓:↓↓.↓↓[↓↓,↓↓]");
         PRSFIL(FN);
         UOUTSTR("FILE:");
         IF LENGTH(FN←UINCHWL)≠0 THEN
            BEGIN
            PUTPFL(PIC[0],FN);
            FN←DEVPRS&":"&FILPRS; OUTSTR("wrote "&DEVPRS&":"&FILPRS&'15&'12);
            END
         ELSE OUTSTR("aborted "&DEVPRS&":"&FILPRS&'15&'12);
         END
      ELSE
      IF CHR="D"∨CHR="∂" THEN	comment  video synthesizer display;
         BEGIN
         INTEGER I,J;
         REAL SX,SY,ASP,ASPEN;
         REAL PX,PY; INTEGER MODP;

         SYNLAS←TRUE;

         MODP←SYPOS MOD (SDISWID*SDISHIG);
         PX←MODP MOD SDISWID;
         MODP←MODP%SDISWID;
         PY←SDISHIG-MODP-1;
         PX←2*PX-SDISWID+1;
         PY←2*PY-SDISHIG+1;

         SX←1; SY←1; ASPEN←SASPECT*SDISWID/SDISHIG;
         ASP←PIC[PCLN]/PIC[LNBY];
         IF ASP>ASPEN THEN SX←ASPEN/ASP ELSE SY←ASP/ASPEN;

         SX←SX*SSIZE;  SY←SY*SSIZE;

         SETFORMAT(0,2);
         SCREEN(-SDISWID,-SDISHIG,SDISWID,SDISHIG);

         MAPGRY(MAPTF,MAPBT); GRAY(PIC[0]);
         I←PIC[BYBI];
         IF SYNMAP(I)>0 ∨ SDISHIG*SDISWID>1 THEN
            BEGIN
            IF SDISHIG*SDISWID>1 THEN GETDDF("DSK:DD"&CVS(I)&".TMP[TMP,HPM]");
            DRKEN; RECTAN(PX-1,PY-1,PX+1,PY+1);
            VID(LXB←PX-SX,LYB←PY-SY,UXB←PX+SX,UYB←PY+SY,PIC[0],1);
            IF CHR="∂" THEN
               BEGIN
               INTEGER I;
               LITEN;
               FOR I←0 STEP 1 UNTIL 4 DO
                  BEGIN
                  LINE(LXB+(UXB-LXB)*I/4,LYB,LXB+(UXB-LXB)*I/4,UYB);
                  LINE(LXB,LYB+(UYB-LYB)*I/4,UXB,LYB+(UYB-LYB)*I/4);
                  END;
               END;
            IF SYNMAP(I)>0 THEN
               BEGIN
               ERASE(SYNMAP(I));
               FOR J←1,1,1 DO DPYUP(SYNMAP(I));
               END;
            IF SDISHIG*SDISWID>1 THEN PUTDDF("DSK:DD"&CVS(I)&".TMP[TMP,HPM]");
            END;
         FOR I←PIC[BYBI]-1 STEP -1 UNTIL 0 DO
         IF SYNMAP(I)>0 ∨ SDISHIG*SDISWID>1 THEN
            BEGIN
            IF SDISHIG*SDISWID>1 THEN GETDDF("DSK:DD"&CVS(I)&".TMP[TMP,HPM]");
            DRKEN; RECTAN(PX-1,PY-1,PX+1,PY+1);
            VID(LXB←PX-SX,LYB←PY-SY,UXB←PX+SX,UYB←PY+SY,
                PIC[0],1 LSH (PIC[BYBI]-1-I));
            IF CHR="∂" THEN
               BEGIN
               INTEGER I;
               LITEN;
               FOR I←0 STEP 1 UNTIL 4 DO
                  BEGIN
                  LINE(LXB+(UXB-LXB)*I/4,LYB,LXB+(UXB-LXB)*I/4,UYB);
                  LINE(LXB,LYB+(UYB-LYB)*I/4,UXB,LYB+(UYB-LYB)*I/4);
                  END;
               END;
            IF SYNMAP(I)>0 THEN
               BEGIN
               ERASE(SYNMAP(I));
               FOR J←1,1,1 DO DPYUP(SYNMAP(I));
               END;
            IF SDISHIG*SDISWID>1 THEN PUTDDF("DSK:DD"&CVS(I)&".TMP[TMP,HPM]");
            END;
         UNGRAY(PIC[0]);
         HAFTONE←TRUE;
         SYPOS←SYPOS+1;
         OUTSTR("*");
         SHOW('47);
         DO BACKLOG←UINCHRW UNTIL BACKLOG≠'15∧BACKLOG≠'12;
         SHOW(-1);
         END
      ELSE
      IF CHR="∃" THEN	comment  quick and dirty video synthesizer display;
         BEGIN
         INTEGER I,J;

         SYNLAS←TRUE;

         SETFORMAT(0,2);
         SCREEN(-SDISWID,-SDISHIG,SDISWID,SDISHIG);

         MAPGRY(MAPTF,PIC[BYBI]); GRAY(PIC[0]);
         FOR I←PIC[BYBI]-1 STEP -1 UNTIL 0 DO
         IF SYNMAP(I)>0 THEN
            BEGIN
            DRKEN; RECTAN(-100,-100,100,100);
            VIDONE(PIC[0],1 LSH (PIC[BYBI]-1-I),
                   (481-(PIC[PCLN] MIN 481))%2,
                   (512-(PIC[LNBY] MIN 512))%2);
            IF SYNMAP(I)>0 THEN
               BEGIN
               ERASE(SYNMAP(I));
               DPYUP(SYNMAP(I));
               END;
            END;
         UNGRAY(PIC[0]);
         HAFTONE←TRUE;
         OUTSTR("*");
         SHOW('47);
         DO BACKLOG←UINCHRW UNTIL BACKLOG≠'15∧BACKLOG≠'12;
         SHOW(-1);
         END
      ELSE
      IF CHR="H" THEN	comment  high quality halftone;
         BEGIN
         INTEGER J,CHN;
         REAL SX,SY,ASP,ASPEN;
         REAL PX,PY; INTEGER MODP;

         SYNLAS←FALSE;

         MODP←HAPOS MOD (HDISWID*HDISHIG);
         PX←MODP MOD HDISWID;
         MODP←MODP%HDISWID;
         PY←HDISHIG-MODP-1;
         PX←2*PX-HDISWID+1;
         PY←2*PY-HDISHIG+1;

         SX←1; SY←1; ASPEN←HASPECT*HDISWID/HDISHIG;
         ASP←PIC[PCLN]/PIC[LNBY];
         IF ASP>ASPEN THEN SX←ASPEN/ASP ELSE SY←ASP/ASPEN;

         SX←SX*HSIZE; SY←SY*HSIZE;

         SCREEN(-HDISWID,-HDISHIG,HDISWID,HDISHIG);
         IF HDISHIG*HDISWID>1 THEN GETDDF("DSK:DD.TMP[TMP,HPM]");
         DRKEN; RECTAN(PX-1,PY-1,PX+1,PY+1);
         VIDEO(LXB←PX-SX,LYB←PY-SY,UXB←PX+SX,UYB←PY+SY,PIC[0],-2);
         CHN←GDDCHN(-1);
         ERASE(CHN);
         FOR J←1,1,1,1,1,1 DO DPYUP(CHN);
         OUTSTR(" CHANNEL "&CVOS(CHN)&'15&'12);
         SHOW(CHN);
	 HAFTONE←TRUE;
         IF HDISHIG*HDISWID>1 THEN PUTDDF("DSK:DD.TMP[TMP,HPM]");
         HAPOS←HAPOS+1;
         OUTSTR("*");
         DO BACKLOG←UINCHRW UNTIL BACKLOG≠'15∧BACKLOG≠'12;
         SHOW(-1);
         RDDCHN(CHN);
         END
      ELSE
      IF CHR="R" THEN	comment  random halftone;
         BEGIN
         INTEGER J,CHN;
         REAL SX,SY,ASP,ASPEN;
         REAL PX,PY; INTEGER MODP;

         SYNLAS←FALSE;

         MODP←HAPOS MOD (HDISWID*HDISHIG);
         PX←MODP MOD HDISWID;
         MODP←MODP%HDISWID;
         PY←HDISHIG-MODP-1;
         PX←2*PX-HDISWID+1;
         PY←2*PY-HDISHIG+1;

         SX←1; SY←1; ASPEN←HASPECT*HDISWID/HDISHIG;
         ASP←PIC[PCLN]/PIC[LNBY];
         IF ASP>ASPEN THEN SX←ASPEN/ASP ELSE SY←ASP/ASPEN;

         SX←SX*HSIZE; SY←SY*HSIZE;

         SCREEN(-HDISWID,-HDISHIG,HDISWID,HDISHIG);
         IF HDISHIG*HDISWID>1 THEN GETDDF("DSK:DD.TMP[TMP,HPM]");
         DRKEN; RECTAN(PX-1,PY-1,PX+1,PY+1);
         VID(LXB←PX-SX,LYB←PY-SY,UXB←PX+SX,UYB←PY+SY,PIC[0],-1);
         CHN←GDDCHN(-1);
         OUTSTR(" CHANNEL "&CVOS(CHN)&'15&'12);
         ERASE(CHN);
         FOR J←1,1,1,1,1,1 DO DPYUP(CHN);
         SHOW(CHN);
	 HAFTONE←TRUE;
         IF HDISHIG*HDISWID>1 THEN PUTDDF("DSK:DD.TMP[TMP,HPM]");
         HAPOS←HAPOS+1;
         OUTSTR("*");
         DO BACKLOG←UINCHRW UNTIL BACKLOG≠'15∧BACKLOG≠'12;
         SHOW(-1);
         RDDCHN(CHN);
         END
      ELSE
      IF CHR="A" THEN	comment  arty bug halftone;
         BEGIN
         INTEGER J,CHN;
         REAL SX,SY,ASP,ASPEN;
         REAL PX,PY; INTEGER MODP;

         SYNLAS←FALSE;

         MODP←HAPOS MOD (HDISWID*HDISHIG);
         PX←MODP MOD HDISWID;
         MODP←MODP%HDISWID;
         PY←HDISHIG-MODP-1;
         PX←2*PX-HDISWID+1;
         PY←2*PY-HDISHIG+1;

         SX←1; SY←1; ASPEN←HASPECT*HDISWID/HDISHIG;
         ASP←PIC[PCLN]/PIC[LNBY];
         IF ASP>ASPEN THEN SX←ASPEN/ASP ELSE SY←ASP/ASPEN;

         SX←SX*HSIZE; SY←SY*HSIZE;

         SCREEN(-HDISWID,-HDISHIG,HDISWID,HDISHIG);
         IF HDISHIG*HDISWID>1 THEN GETDDF("DSK:DD.TMP[TMP,HPM]");
         DRKEN; RECTAN(PX-1,PY-1,PX+1,PY+1);
         VIDEO(LXB←PX-SX,LYB←PY-SY,UXB←PX+SX,UYB←PY+SY,PIC[0],-4);
         CHN←GDDCHN(-1);
         ERASE(CHN);
         FOR J←1,1,1,1,1,1 DO DPYUP(CHN);
         OUTSTR(" CHANNEL "&CVOS(CHN)&'15&'12);
         SHOW(CHN);
	 HAFTONE←TRUE;
         IF HDISHIG*HDISWID>1 THEN PUTDDF("DSK:DD.TMP[TMP,HPM]");
         HAPOS←HAPOS+1;
         OUTSTR("*");
         DO BACKLOG←UINCHRW UNTIL BACKLOG≠'15∧BACKLOG≠'12;
         SHOW(-1);
         RDDCHN(CHN);
         END
      ELSE
      IF CHR="X" THEN	comment  send previous halftone to the XGP;
         BEGIN
         INTEGER J;
	 UOUTSTR("SIZE (-5 to +5):");
	 J←CVD(UINCHWL);
         IF J≠0 THEN
            BEGIN
            IF HAFTONE THEN BEGIN INVEN; RECTAN(-1000,-1000,1000,1000); END;
            XGPUP(J);
            IF HAFTONE THEN BEGIN INVEN; RECTAN(-1000,-1000,1000,1000); END;
            END
	 ELSE
	    OUTSTR("aborted "&DEVPRS&":"&FILPRS&'15&'12);
         END
      ELSE
      IF CHR=">" THEN	comment  make a DD buffer into an MIT transferrable file;
         BEGIN
         OWN STRING FN;
         PRSFIL("↓↓:↓↓.↓↓[↓↓,↓↓]");
         PRSFIL("DSK:.SU");
         PRSFIL(FN);
         UOUTSTR("OUTPUT FILE NAME:");
         IF ¬PUTMIT(UINCHWL) THEN OUTSTR("aborted "&DEVPRS&":"&FILPRS&'15&'12)
         ELSE
            BEGIN
            FN←DEVPRS&":"&FILPRS; OUTSTR("wrote "&DEVPRS&":"&FILPRS&'15&'12);
            END;
         END
      ELSE
      IF CHR="<" THEN	comment  display MIT transferrable file;
         BEGIN
         OWN STRING FN;
         INTEGER J,CHN;
         PRSFIL("↓↓:↓↓.↓↓[↓↓,↓↓]");
         PRSFIL("DSK:.MIT");
         PRSFIL(FN);
         UOUTSTR("INPUT FILE NAME:");
         DRKEN; RECTAN(-100,-100,100,100);
         IF ¬GETMIT(UINCHWL) THEN OUTSTR("aborted "&DEVPRS&":"&FILPRS&'15&'12)
         ELSE
            BEGIN
	    CHN←GDDCHN(-1);
	    OUTSTR(" CHANNEL "&CVOS(CHN)&'15&'12);
	    ERASE(CHN);
	    FOR J←1,1,1,1,1 DO DPYUP(CHN);
	    SHOW(CHN);
	    OUTSTR("*");
	    DO BACKLOG←UINCHRW UNTIL BACKLOG≠'15∧BACKLOG≠'12;
	    RDDCHN(CHN);
	    SHOW(-1);
            FN←DEVPRS&":"&FILPRS;
            END;
         END
      ELSE
      IF CHR="#" THEN	comment  switch a video switch output;
         BEGIN
         INTEGER J,K;
	 UOUTSTR(" LINE:"); J←CVO(UINCHWL);
	 UOUTSTR("CHANNEL:"); K←CVO(UINCHWL);
         SHOW(K,J);
         END
      ELSE
      IF CHR="P" THEN	comment  list a picture on the tty;
         BEGIN
         INTEGER I,J,K,L,M;
         REAL ASP;
         INTEGER SX,SY;

         ASP←PIC[PCLN]/PIC[LNBY];

         SX←TWID; SY←SX*ASP*TASPECT;

         IF SY>TLEN THEN BEGIN SX←SX*TLEN/SY; SY←TLEN; END;

            BEGIN
            REAL PCMAX;

            PCMAX←2↑PIC[BYBI]-1;

            CALL(0,"RESET");

            OUTSTR('15&'12);
            FOR J←0 STEP 1 UNTIL SY-1 DO
              BEGIN
              FOR I←0 STEP 1 UNTIL SX-1 DO
                 BEGIN
                 PRELOAD_WITH " ","`",".","-","'","/",":","+","1","[","0",
                    "X","%","A","Q","M","*";
                 OWN INTEGER ARRAY GRT[0:16];
                 IF TBRITE THEN
                 OUTSTR(GRT[16*PIXEL(PIC[0],PIC[PCLN]*J%SY,PIC[LNBY]*I%SX)/PCMAX])
                 ELSE
                 OUTSTR(GRT[16*
                           (1-PIXEL(PIC[0],PIC[PCLN]*J%SY,PIC[LNBY]*I%SX)/PCMAX)]);
                 END;
               OUTSTR('15&'12);
               END;
            END;
         END
      ELSE
      IF CHR="α" THEN	comment  add a letter to a font;
         BEGIN
         INTEGER LETR;  OWN STRING FOFIL;

         PRSFIL("↓↓:↓↓.↓↓[↓↓,↓↓]");
         PRSFIL(".FNT");
         PRSFIL(FOFIL);
         UOUTSTR("FONT FILE:"); FOFIL←UINCHWL;
         UOUTSTR("LETTER:"); LETR←UINCHWL;
         DDFONT(LXB,LYB,UXB,UYB, FOFIL, LETR);
         FOFIL←DEVPRS&":"&FILPRS; OUTSTR("wrote "&DEVPRS&":"&FILPRS&'15&'12);
         END
      ELSE
      IF CHR="π" THEN comment  output dd buf to jarvis term.;
         begin
         if ¬pjup then outstr("failed") else show('41);
         end
      ELSE
      IF CHR="λ" THEN	comment  make an XGPable file;
         BEGIN
         INTEGER I,J,K,L,M;  REAL D,G,O;  STRING S; OWN STRING FN;
         PRSFIL("↓↓:↓↓.↓↓[↓↓,↓↓]");
         PRSFIL(".TXT");
         PRSFIL(FN);
	 DO
	   BEGIN
	   UOUTSTR("XGP OUTPUT FILE NAME:");
           PRSFIL(FN←UINCHWL);
           M←1;
           OPEN(1,DEVPRS,0,0,3,0,0,M);
	   ENTER(1,FILPRS,M);
	   END
         UNTIL ¬M;
         UOUTSTR("DENSITY (0 (normal) to 1):"); D←REALSCAN(S←UINCHWL,M);
         O←'77+'40*D; G←(D+1)*'40/2↑PIC[BYBI];
	 FOR I←0 STEP 1 UNTIL PIC[PCLN]-1 DO
            BEGIN
            FOR J←0 STEP 1 UNTIL PIC[LNBY]-1 DO
               OUT(1,M←O-G*PIXEL(PIC[0],I,J));
            OUT(1,'15&'12);
            END;
         CLOSE(1);
         FN←DEVPRS&":"&FILPRS; OUTSTR("wrote "&DEVPRS&":"&FILPRS&'15&'12);
         END
      ELSE
      IF CHR="C" THEN	comment  step past a certain number of pictures;
         BEGIN
         INTEGER T;
         UOUTSTR("SKIP HOW MANY (NEGATIVE TO BACKSPACE):");
         T←CVD(UINCHWL);
         IF SYNLAS THEN SYPOS←SYPOS+T ELSE HAPOS←HAPOS+T;
         END
      ELSE
      IF CHR="K" THEN	comment  clear the video synthesizer;
         BEGIN
	 INTEGER T;
	 FOR T←0 STEP 1 UNTIL 7 DO ERASE(SYNMAP(T));
         END
      ELSE
      IF CHR="≡" THEN	comment  gronk synthesizer intensity table;
         BEGIN
 	 STRING SI; INTEGER I;

 	 UOUTSTR("TRANSFER FUNCTION (about -2.0 to 2.0):");
 	 IF ¬MAPGRY(MAPTF←REALSCAN(SI←UINCHWL,I),MAPBT) THEN
            OUTSTR("failed"&'15&'12);

         END
      ELSE
      IF CHR="S" THEN	comment  change size of displays;
         BEGIN
         STRING INP; INTEGER FOO,INC;
         REAL T;
         UOUTSTR("FOR SYNTHESIZER, HALFTONES OR PRINTOUT (S, H OR P)?"); 
         INC←UCONV(UINCHWL);
         IF INC="S" THEN
            BEGIN
            INTEGER I;
            SYNLAS←TRUE;
            SETFORMAT(0,2);
            UOUTSTR("PICTURE SIZE (1 IS FULLSIZE, NOW"&CVF(SSIZE)&"):"); INP←UINCHWL;
            T←REALSCAN(INP,FOO);
            IF T≠0 THEN SSIZE←ABS(T);
            UOUTSTR("ASPECT RATIO (HEIGHT/WIDTH OF SCREEN, NOW"&CVF(SASPECT)&"):");
            INP←UINCHWL;
            T←REALSCAN(INP,FOO);
            IF T>0 THEN SASPECT←T;
            UOUTSTR("NUMBER OF PICTURES IN X DIRECTION:"); 
            T←ABS(CVD(UINCHWL));
            IF T>0∧T≠SDISWID THEN
               BEGIN
               SDISWID←T;
               SYPOS←0;
               END;
            UOUTSTR("NUMBER OF PICTURES IN Y DIRECTION:"); 
            T←ABS(CVD(UINCHWL));
            IF T>0∧T≠SDISHIG THEN
               BEGIN
               SDISHIG←T;
               SYPOS←0;
               END;
            SCREEN(-1,-1,1,1);
            DRKEN; RECTAN(-1000,-1000,1000,1000);
            IF SDISHIG*SDISWID>1 THEN
               BEGIN
               UOUTSTR("ERASE?");
               IF UCONV(UINCHWL)="Y" THEN
               FOR I←0 STEP 1 UNTIL 7 DO
                  PUTDDF("DSK:DD"&CVS(I)&".TMP[TMP,HPM]")
               ELSE
                  BEGIN
                  UOUTSTR("REDRAW OLD DISPLAY NOW?");
                  IF UCONV(UINCHWL)="Y" THEN
                  FOR I←7 STEP -1 UNTIL 0 DO
                  IF SYNMAP(I)≥0 THEN
                     BEGIN
                     IF I=0 THEN MAPGRY(MAPTF,MAPBT);
		     SHOWA('47);
                     GETDDF("DSK:DD"&CVS(I)&".TMP[TMP,HPM]");
                     ERASE(SYNMAP(I));
                     DPYUP(SYNMAP(I)); DPYUP(SYNMAP(I));
                     DPYUP(SYNMAP(I)); DPYUP(SYNMAP(I));
		     SHOWA('47);
                     END;
                  HAFTONE←TRUE;
                  OUTSTR("*");
                  DO BACKLOG←UINCHRW UNTIL BACKLOG≠'15∧BACKLOG≠'12;
                  END;
               END;
            END
         ELSE IF INC="H" THEN
            BEGIN
            SYNLAS←FALSE;
            SETFORMAT(0,2);
            UOUTSTR("PICTURE SIZE (1 IS FULLSIZE, NOW"&CVF(HSIZE)&"):"); INP←UINCHWL;
            T←REALSCAN(INP,FOO);
            IF T≠0 THEN HSIZE←ABS(T);
            UOUTSTR("ASPECT RATIO (HEIGHT/WIDTH OF SCREEN, NOW"&CVF(HASPECT)&"):");
            INP←UINCHWL;
            T←REALSCAN(INP,FOO);
            IF T>0 THEN HASPECT←T;
            UOUTSTR("NUMBER OF PICTURES IN X DIRECTION:"); 
            T←ABS(CVD(UINCHWL));
            IF T>0∧T≠HDISWID THEN
               BEGIN
               HDISWID←T;
               HAPOS←0;
               END;
            UOUTSTR("NUMBER OF PICTURES IN Y DIRECTION:"); 
            T←ABS(CVD(UINCHWL));
            IF T>0∧T≠HDISHIG THEN
               BEGIN
               HDISHIG←T;
               HAPOS←0;
               END;
            SCREEN(-1,-1,1,1);
            DRKEN; RECTAN(-1000,-1000,1000,1000);
            IF HDISHIG*HDISWID>1 THEN PUTDDF("DSK:DD.TMP[TMP,HPM]");
            END
         ELSE IF INC="P" THEN
            BEGIN
            SETFORMAT(0,2);
            UOUTSTR("ASPECT RATIO OF TTY (CHRS/IN, VERTICAL/HORIZONTAL, NOW "&
               CVF(TASPECT)&"):");
            INP←UINCHWL;
            T←REALSCAN(INP,FOO);
            IF T≠0 THEN TASPECT←ABS(T);
            UOUTSTR("WIDTH OF TTY DISPLAYS (NOW "&CVS(TWID)&"):");
            INP←UINCHWL;
            T←REALSCAN(INP,FOO);
            IF T≠0 THEN TWID←ABS(T);
            UOUTSTR("MAXIMUM HEIGHT OF TTY DISPLAYS (NOW "&CVS(TLEN)&"):");
            INP←UINCHWL;
            T←REALSCAN(INP,FOO);
            IF T≠0 THEN TLEN←ABS(T);
            UOUTSTR("ARE LETTERS BRIGHT OR DARK (NOW "&
               (IF TBRITE THEN "BRIGHT" ELSE "DARK")&"):");
            TBRITE←¬(UCONV(UINCHWL)="D");
            END;
         END
      ELSE
      IF CHR="F" THEN	comment  high pass filter;
         BEGIN
         INTEGER WINDOW;

         UOUTSTR(" WINDOW SIZE:");
         WINDOW←CVD(UINCHWL);
         IF WINDOW>1 THEN
            BEGIN
            INTEGER ARRAY T[0:PHAVE];
            PASSHI(PIC[0],WINDOW,T[0]);
            ENHANCE(T[0]);
            COPPIC(T[0],PIC[0]);
            END
         ELSE OUTSTR("aborted "&DEVPRS&":"&FILPRS&'15&'12);

         END
      ELSE
      IF CHR="&" THEN	comment  measure noise;
         BEGIN
         OUTSTR(" NOISE FIGURE:"&CVF(NOISE(PIC[0]))&'15&'12);
         END
      ELSE
      IF CHR="L" THEN	comment  low pass filter;
         BEGIN
         INTEGER ARRAY T[0:PHAVE];
         IF PIC[PCLN]≥2∧PIC[LNBY]≥2 THEN
            BEGIN
            HAFPIC(PIC[0],T[0],8);
            COPPIC(T[0],PIC[0]);
            END;
         PWANT←PHAVE←PIXDIM(PIC[PCLN],PIC[LNBY],PIC[BYBI]);
         INITED←FALSE;
         OUTSTR(CVS(PIC[PCLN])&" LINES x "&CVS(PIC[LNBY])&
            " BYTES/LINE x "&CVS(PIC[BYBI])&" BITS/BYTE"&'15&'12);
         END
      ELSE
      IF CHR="W" THEN	comment  select a window;
         BEGIN
         INTEGER XL,XH,YL,YH,FOO; REAL A,B;
         STRING INFL;

         UOUTSTR("LOW X, HIGH X (PIXELS OR FRACTION):"); INFL←UINCHWL;
         XL←A←REALSCAN(INFL,FOO);
         XH←B←REALSCAN(INFL,FOO);
         IF ABS(A)≤1 ∧ ABS(B)≤1 THEN
            BEGIN
            XL←A*PIC[LNBY];
            XH←B*PIC[LNBY];
            END;

         IF XL>XH THEN XL↔XH;
         XL←XL MAX 0; XH←XH MIN (PIC[LNBY]-1);
         IF (XH-XL+1)>0 THEN
            BEGIN
            UOUTSTR("LOW Y, HIGH Y:"); INFL←UINCHWL;
            YL←A←REALSCAN(INFL,FOO);
            YH←B←REALSCAN(INFL,FOO);
            IF ABS(A)≤1 ∧ ABS(B)≤1 THEN
               BEGIN
               YL←A*PIC[PCLN];
               YH←B*PIC[PCLN];
               END;
            IF YL>YH THEN YL↔YH;
            YL←YL MAX 0; YH←YH MIN (PIC[PCLN]-1);
            IF (YH-YL+1)>0 THEN
               BEGIN
               INTEGER ARRAY T[0:PIXDIM(YH-YL+1,XH-XL+1,PIC[BYBI])];
               MAKPIX(YH-YL+1,XH-XL+1,PIC[BYBI],T[0]);
               SELECT(PIC[0],YL,XL,T[0]);
               COPPIC(T[0],PIC[0]);
               OUTSTR(CVS(PIC[PCLN])&" LINES x "&CVS(PIC[LNBY])&
                  " BYTES/LINE x "&CVS(PIC[BYBI])&" BITS/BYTE"&'15&'12);
               PWANT←PHAVE←PIXDIM(PIC[PCLN],PIC[LNBY],PIC[BYBI]);
               INITED←FALSE;
               END;
            END;

         END
      ELSE
      IF CHR="Z" THEN	comment  change size of a picture;
         BEGIN
         OWN INTEGER LHIG,LWID,LBITS;
         INTEGER FOO;
         STRING INFL;

         IF LENGTH(BACKLOG)=0 THEN
            BEGIN
            UOUTSTR("DILATION FACTORS (EG. .5 = HALF SIZE) Y, X:"); INFL←UINCHWL;
            LHIG←ABS(REALSCAN(INFL,FOO))*PIC[PCLN]; IF LHIG=0 THEN LHIG←PIC[PCLN];
            LWID←ABS(REALSCAN(INFL,FOO))*PIC[LNBY]; IF LWID=0 THEN LWID←PIC[LNBY];
            UOUTSTR("NUMBER OF BITS:");  LBITS←(CVD(UINCHWL) MIN 36);
            IF LBITS≤0 THEN LBITS←PIC[BYBI];

            IF LBITS≠PIC[BYBI]∨LWID≠PIC[LNBY]∨LHIG≠PIC[PCLN] THEN
                BEGIN
	        PUTPFL(PIC[0],"DSK:TMP.TMP[TMP,HPM]");
                PWANT←PIXDIM(LHIG,LWID,LBITS);
                BACKLOG←"Z ";
                END;
            END
         ELSE
            BEGIN
            INTEGER ARRAY T[0:PFLDIM("TMP.TMP[TMP,HPM]")];
            GETPFL("DSK:TMP.TMP[TMP,HPM]",T[0]);
	    MAKPIX(LHIG,LWID,LBITS,PIC[0]);
            OUTSTR(CVS(PIC[PCLN])&" LINES x "&CVS(PIC[LNBY])&
               " BYTES/LINE x "&CVS(PIC[BYBI])&" BITS/BYTE"&'15&'12);
            SHRINK(T[0],PIC[0]);
            BACKLOG←"";
            INITED←FALSE;
            END;
         END
      ELSE
      IF CHR="ε" THEN	comment  make DD buffer into a picture;
         BEGIN
         OWN INTEGER LHIG,LWID,LBITS;

         IF LENGTH(BACKLOG)=0 THEN
            BEGIN
            LHIG←481; LWID←512; LBITS←1;
	    PWANT←PIXDIM(HIG,WID,BITS);
	    BACKLOG←"ε ";
            END
         ELSE
            BEGIN
            INTEGER I;
	    MAKPIX(LHIG,LWID,LBITS,PIC[0]);
            OUTSTR(CVS(PIC[PCLN])&" LINES x "&CVS(PIC[LNBY])&
               " BYTES/LINE x "&CVS(PIC[BYBI])&" BITS/BYTE"&'15&'12);
	    FOR I ← 0 STEP 1 UNTIL 480 DO
		    DDPAK(I,MEMORY[PIC[LINTAB+I]],0,511);
            BACKLOG←"";
            INITED←FALSE;
            END;
         END
      ELSE
      IF CHR="*" THEN	comment  general geometric transformation;
         BEGIN
         OWN INTEGER HIG,WID,BITS;
         INTEGER FOO;
         STRING INFL;
         own string tr1,tr2,tr3;

         IF LENGTH(BACKLOG)=0 THEN
            BEGIN
            integer com;
            UOUTSTR("Transform (? for help):"); com←UINCHRW;
            WHILE com="?" DO
               BEGIN
               Uoutstr("
R           Rotate
E           Enter transform matrix

Transform:");
               com←UINCHRW;
               END;

            COM←COM LAND '137;
            if com="R" then
               begin
               REAL RT,SRT,CRT;
               UOUTSTR("What fraction of a full turn:");
               RT←REALSCAN(INFL←UINCHWL,FOO);
               SRT←SIN(2*3.14159265*RT); CRT←COS(2*3.14159265*RT);
               SETFORMAT(0,4);
               TR1←CVF(CRT)&" "&CVF(SRT)&" "&CVF(.5*(1-SRT-CRT));
               TR2←CVF(-SRT)&" "&CVF(CRT)&" "&CVF(.5*(1+SRT-CRT));
               TR3←"0 0 1";
               HIG←PIC[PCLN]*ABS(CRT)+PIC[LNBY]*ABS(SRT);
               WID←PIC[LNBY]*ABS(CRT)+PIC[PCLN]*ABS(SRT);
               RT←SQRT(PIC[PCLN]*PIC[LNBY]/(HIG*WID));
               HIG←HIG*RT+.5;
               WID←WID*RT+.5;
               BITS←PIC[BYBI];
               PUTPFL(PIC[0],"DSK:TMP.TMP[TMP,HPM]");
               end
            else if com="E" then 
               begin
               Uoutstr("Enter transform matrix."&'15&'12);
               Uoutstr("tr[1,1:3] ← ");loded(tr1&'12);tr1←UINCHWL;
               Uoutstr("tr[2,1:3] ← ");loded(tr2&'12);tr2←UINCHWL;
               Uoutstr("tr[3,1:3] ← ");loded(tr3&'12);tr3←UINCHWL;
               Uoutstr("height width bits ← ");
                  loded(cvs(pic[pcln])&" "&cvs(pic[lnby])
                  &" "&cvs( pic[bybi] ) & '12); infl ← UINCHWL;
               hig←intscan(infl,foo);
               wid←intscan(infl,foo);
               bits←intscan(infl,foo);
               PUTPFL(PIC[0],"DSK:TMP.TMP[TMP,HPM]");
               end;

            PWANT←PIXDIM(HIG,WID,BITS);
            BACKLOG←"* ";
            END
         ELSE
            BEGIN
            INTEGER ARRAY T[0:PFLDIM("DSK:TMP.TMP[TMP,HPM]")];
            real array tr[1:3,1:3];
            GETPFL("DSK:TMP.TMP[TMP,HPM]",T[0]);
            MAKPIX(HIG,WID,BITS,PIC[0]);
            OUTSTR(CVS(PIC[PCLN])&" LINES x "&CVS(PIC[LNBY])&
               " BYTES/LINE x "&CVS(PIC[BYBI])&" BITS/BYTE"&'15&'12);
            infl←tr1;tr[1,1]←realscan(infl,foo);tr[1,2]←realscan(infl,foo);tr[1,3]←realscan(infl,foo);
            infl←tr2;tr[2,1]←realscan(infl,foo);tr[2,2]←realscan(infl,foo);tr[2,3]←realscan(infl,foo);
            infl←tr3;tr[3,1]←realscan(infl,foo);tr[3,2]←realscan(infl,foo);tr[3,3]←realscan(infl,foo);
            pixtrn(t[0],tr,pic[0]);
            BACKLOG←"";
            INITED←FALSE;
            END;
         END
      ELSE
      IF CHR="U" THEN	comment  remove blank border from a picture;
         BEGIN
         INTEGER ARRAY ROW[0:PIC[PCLN]-1],COL[0:PIC[LNBY]-1];
         INTEGER FHX,FHY,I,K,FLX,FLY;

         ROWSUM(PIC[0],ROW[0]);
         K←0; FOR I←0 STEP 1 UNTIL PIC[PCLN]-1 DO K←K+ROW[I];
         K←K/PIC[PCLN]; FLY←0; WHILE ROW[FLY]<K/2 DO FLY←FLY+1;
              FHY←PIC[PCLN]-1; WHILE ROW[FHY]<K/2 DO FHY←FHY-1;
         IF ROW[FLY]<K/1.5 THEN FLY←FLY+1;
         IF ROW[FLY]<K/1.5 THEN FLY←FLY+1;

         COLSUM(PIC[0],COL[0]);
         K←0; FOR I←0 STEP 1 UNTIL PIC[LNBY]-1 DO K←K+COL[I];
         K←K/PIC[LNBY]; FLX←0; WHILE COL[FLX]<K/2 DO FLX←FLX+1;
              FHX←PIC[LNBY]-1; WHILE COL[FHX]<K/2 DO FHX←FHX-1;

         WID←FHX-FLX+1; HIG←FHY-FLY+1;

         IF BITS≠PIC[BYBI]∨WID≠PIC[LNBY]∨HIG≠PIC[PCLN] THEN
            BEGIN
            INTEGER ARRAY T[0:PHAVE];

	    COPPIC(PIC[0],T[0]);
            MAKPIX(HIG,WID,BITS,PIC[0]);
            SELECT(T[0],FLY,FLX,PIC[0]);
            OUTSTR(CVS(PIC[PCLN])&" LINES x "&CVS(PIC[LNBY])&
               " BYTES/LINE x "&CVS(PIC[BYBI])&" BITS/BYTE"&'15&'12);
            PHAVE←PWANT←PIXDIM(HIG,WID,BITS);
            INITED←FALSE;
            END;
         END
      ELSE
      IF CHR="N" THEN	comment  apply noise remover;
         BEGIN
         CLEAN(PIC[0]);
         END
      ELSE
      IF CHR="V" THEN	comment  apply interest operator;
         BEGIN
         INTEGER WINDOW;
         UOUTSTR(" WINDOW SIZE:"); WINDOW←CVD(UINCHWL);
         IF WINDOW≥1 THEN
            BEGIN
            INTEREST(PIC[0],WINDOW,PIC[0]);
            OUTSTR(CVS(PIC[PCLN])&" LINES x "&CVS(PIC[LNBY])&
               " BYTES/LINE x "&CVS(PIC[BYBI])&" BITS/BYTE"&'15&'12);
            PWANT←PHAVE←PIXDIM(PIC[PCLN],PIC[LNBY],PIC[BYBI]);
            INITED←FALSE;
            END
         ELSE OUTSTR("aborted "&DEVPRS&":"&FILPRS&'15&'12);
            
         END
      ELSE
      IF CHR="M" THEN	comment  pixel modification;
         BEGIN
         PRELOAD_WITH -1;
         OWN INTEGER ARRAY PERM[-1:1024];
         STRING INP; INTEGER FOO,I,J;
         INTEGER LAST,THIS;

         IF PERM[-1]=PIC[BYBI] THEN
            BEGIN
            UOUTSTR(" ENTER NEW TRANSFORM?");
            INP←UCONV(UINCHRW);
            END ELSE INP←"Y";
         IF INP="Y" THEN
            BEGIN
	    PERM[-1]←PIC[BYBI];
            UOUTSTR(CVS(2↑PIC[BYBI])&" TOTAL GREY LEVELS, ENTER HOW MANY:");
            FOO←(CVD(UINCHWL) MAX 2) MIN 2↑PIC[BYBI];
            LAST←0;
            FOR I←0 STEP 1 UNTIL FOO-1 DO
               BEGIN
               THIS←((1 ASH PIC[BYBI])-1)*I%(FOO-1);
               UOUTSTR(CVS(THIS)&"→");
               PERM[THIS]←CVD(UINCHWL);
               IF THIS>LAST THEN
               FOR J←LAST STEP 1 UNTIL THIS DO
                  PERM[J]←(PERM[LAST]*(THIS-J)+PERM[THIS]*(J-LAST))%(THIS-LAST);
               LAST←THIS;
               END;
            FOR I←0 STEP 1 UNTIL 2↑PIC[BYBI]-1 DO
               PERM[I]←(PERM[I] MAX 0) MIN (2↑PIC[BYBI]-1);
            END;
         PERBIT(PIC[0],PERM[0]);
         END
      ELSE
      IF CHR="G" THEN	comment  graph a histogram;
         BEGIN
         INTEGER ARRAY HIST[0:PIC[BMAX]+1];
         INTEGER FOO,I,J,MAV,CHN;
         CHN←GDDCHN(-1);
         OUTSTR(" CHANNEL "&CVOS(CHN)&'15&'12);
         FOO←2↑PIC[BYBI]-1;
         HISTOG(PIC[0],HIST[0]);
         SCREEN(-.3,-.2,1.1,1.2);
         DRKEN; RECTAN(-100,-100,100,100);
         LITEN;
         LINE(0,0,0,1); LINE(0,1,1,1);
         LINE(1,1,1,0); LINE(1,0,0,0);
         LINE(0,.5,1,.5); LINE(0,.25,1,.25); LINE(0,.75,1,.75);
         LINE(.5,0,.5,1); LINE(.25,0,.25,1); LINE(.75,0,.75,1);
         MAV←0; FOR I←0 STEP 1 UNTIL FOO DO MAV←MAV MAX HIST[I];
         MAV←MAV+1;
         FOR I←1 STEP 1 UNTIL FOO DO
            LINE((I-1)/FOO,HIST[I-1]/MAV,I/FOO,HIST[I]/MAV);
         TXTPOS(0,-1/10,1/24,1/12); TEXT("0");
         TXTPOS(1-LENGTH(CVS(2↑PIC[BYBI]))/24,-1/10,1/24,1/12);
         TEXT(CVS(2↑PIC[BYBI]-1));
         TXTPOS(-.07,0,1/24,1/12); TEXT("0");
         TXTPOS(-.07-(LENGTH(CVS(MAV))-1)/24,1-1/12,1/24,1/12); TEXT(CVS(MAV));
         ERASE(CHN);
         FOR J←1,1,1,1,1 DO DPYUP(CHN);
         HAFTONE←FALSE;  LXB←LYB←-1; UXB←UYB←1;
         SHOW(CHN);
         OUTSTR("*");
         DO BACKLOG←UINCHRW UNTIL BACKLOG≠'15∧BACKLOG≠'12;
         RDDCHN(CHN);
         SHOW(-1);
         END
      ELSE
      IF CHR="J" THEN	comment  graph a histogram;
         BEGIN
         INTEGER ARRAY HIST[0:PIC[BMAX]+1];
         INTEGER FOO,I,J,L,MAV,CHN;
         CHN←GDDCHN(-1);
         OUTSTR(" CHANNEL "&CVOS(CHN)&'15&'12);
         FOO←2↑PIC[BYBI]-1;
         HISTOG(PIC[0],HIST[0]);
         SCREEN(-.3,-.2,1.1,1.2);
         DRKEN; RECTAN(-100,-1000,1000,1000);
         LITEN;
         LINE(0,0,0,1); LINE(0,1,1,1);
         LINE(1,1,1,0); LINE(1,0,0,0);
         LINE(0,.5,1,.5); LINE(0,.25,1,.25); LINE(0,.75,1,.75);
         LINE(.5,0,.5,1); LINE(.25,0,.25,1); LINE(.75,0,.75,1);
         MAV←0; FOR I←0 STEP 1 UNTIL FOO DO MAV←MAV + HIST[I];
         L←J←0;
         FOR I←1 STEP 1 UNTIL FOO DO
            BEGIN
            L←J;
            J←J+HIST[I];
            LINE((I-1)/FOO,L/MAV,I/FOO,J/MAV);
            END;
         TXTPOS(0,-1/10,1/24,1/12); TEXT("0");
         TXTPOS(1-LENGTH(CVS(2↑PIC[BYBI]))/24,-1/10,1/24,1/12);
         TEXT(CVS(2↑PIC[BYBI]-1));
         TXTPOS(-.07,0,1/24,1/12); TEXT("0");
         TXTPOS(-.07-(LENGTH(CVS(MAV))-1)/24,1-1/12,1/24,1/12); TEXT(CVS(MAV));
         ERASE(CHN);
         FOR J←1,1,1,1,1 DO DPYUP(CHN);
         SHOW(CHN);
         HAFTONE←FALSE;  LXB←LYB←-1; UXB←UYB←1;
         OUTSTR("*");
         DO BACKLOG←UINCHRW UNTIL BACKLOG≠'15∧BACKLOG≠'12;
         RDDCHN(CHN);
         SHOW(-1);
         END
      ELSE
      IF CHR="E" THEN	comment  apply histogram normalizer;
         BEGIN
         ENHANCE(PIC[0]);
         END
      ELSE
      IF CHR="Y" THEN	comment  apply vert sync loss correction;
         BEGIN
         SYNCHRONIZE(PIC[0]);
         END
      ELSE
      IF CHR="∞" THEN  comment for hackery;
         BEGIN
         END
      ELSE
      IF CHR="Q" THEN	comment  exit;
         BEGIN
	 if outddcalled then OUTDD('40&'15&'12);
         CALL(0,"EXIT");
         END
      ELSE
         BEGIN       comment  an unrecognized character;
         OUTSTR("?"&'15&'12);
         END;
      END;
   PHAVE←PWANT;
   END;
END "PIX";